#include "graphics.h"
#include "globals.h"

// Initializes the graphics system
int GraphicsClass::Init(int TWidth, int THeight, bool TFullScreen, E_DRIVER_TYPE TDriverType, IEventReceiver *TEventReceiver) 
{
	Width = TWidth;
	Height = THeight;

	SetClearColor(SColor(0));

	// Create the irrlicht device
	irrDevice = createDevice(TDriverType, dimension2du(TWidth, THeight), 32, TFullScreen, true, false, TEventReceiver);
	if(irrDevice == NULL)
		return 0;

	irrDevice->setWindowCaption(L"fonline");
	irrDevice->setEventReceiver(TEventReceiver);

	// Save off global pointers
	irrDriver = irrDevice->getVideoDriver();
	irrScene = irrDevice->getSceneManager();
	irrGUI = irrDevice->getGUIEnvironment();
	irrFile = irrDevice->getFileSystem();
	irrTimer = irrDevice->getTimer();

	// Load skin data
	Skin = irrGUI->getSkin();

	// Load fonts
	Fonts[FONT_7] = irrGUI->getFont("fonts/font_7.xml");
	Fonts[FONT_8] = irrGUI->getFont("fonts/font_8.xml");
	Fonts[FONT_10] = irrGUI->getFont("fonts/font_10.xml");
	Fonts[FONT_14] = irrGUI->getFont("fonts/font_14.xml");
	Fonts[FONT_18] = irrGUI->getFont("fonts/font_18.xml");

	// Set font
	SetFont(FONT_10);

	// Set colors
	Skin->setColor(EGDC_BUTTON_TEXT, SColor(255, 255, 255, 255));
	Skin->setColor(EGDC_WINDOW, SColor(255, 0, 0, 20));	
	Skin->setColor(EGDC_WINDOW_SYMBOL, SColor(255, 255, 255, 255));

	Skin->setColor(EGDC_3D_FACE, SColor(255, 0, 0, 20));
	Skin->setColor(EGDC_3D_SHADOW, SColor(255, 0, 0, 20));

	Skin->setColor(EGDC_3D_HIGH_LIGHT, SColor(255, 120, 120, 120));
	Skin->setColor(EGDC_3D_DARK_SHADOW, SColor(255, 50, 50, 50));

/*
	Skin->setColor(EGDC_3D_DARK_SHADOW, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_3D_SHADOW, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_3D_FACE, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_3D_HIGH_LIGHT, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_3D_LIGHT, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_ACTIVE_BORDER, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_ACTIVE_CAPTION, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_APP_WORKSPACE, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_BUTTON_TEXT, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_GRAY_TEXT, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_HIGH_LIGHT, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_HIGH_LIGHT_TEXT, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_INACTIVE_BORDER, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_INACTIVE_CAPTION, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_TOOLTIP, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_TOOLTIP_BACKGROUND, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_SCROLLBAR, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_WINDOW, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_WINDOW_SYMBOL, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_ICON, SColor(255, 50, 50, 50));
	Skin->setColor(EGDC_ICON_HIGH_LIGHT, SColor(255, 50, 50, 50));
*/

	// Load images
	Images[IMAGE_EMPTYSLOT] = irrDriver->getTexture("textures/interface/emptyslot.png");
	Images[IMAGE_SELECTEDSLOT] = irrDriver->getTexture("textures/interface/selectedslot.png");
	Images[IMAGE_HEALTH] = irrDriver->getTexture("textures/interface/health.png");
	Images[IMAGE_HEALTHMAX] = irrDriver->getTexture("textures/interface/healthmax.png");
	Images[IMAGE_MANA] = irrDriver->getTexture("textures/interface/mana.png");
	Images[IMAGE_MANAMAX] = irrDriver->getTexture("textures/interface/manamax.png");
	Images[IMAGE_EXPERIENCE] = irrDriver->getTexture("textures/interface/experience.png");
	Images[IMAGE_EXPERIENCEMAX] = irrDriver->getTexture("textures/interface/experiencemax.png");
	Images[IMAGE_BLACK] = irrDriver->getTexture("textures/interface/black.png");
	Images[IMAGE_GOLD] = irrDriver->getTexture("textures/interface/gold.png");
	Images[IMAGE_PVP] = irrDriver->getTexture("textures/interface/pvp.png");
	Images[IMAGE_MENULOGO] = irrDriver->getTexture("textures/menu/logo.png");
	Images[IMAGE_MENUBLANKSLOT] = irrDriver->getTexture("textures/menu/blankslot.png");
	Images[IMAGE_MENUSELECTED] = irrDriver->getTexture("textures/menu/selected.png");
	Images[IMAGE_WORLDBUSY] = irrDriver->getTexture("textures/world/busy.png");
	Images[IMAGE_WORLDTRADE] = irrDriver->getTexture("textures/world/trade.png");
	Images[IMAGE_BATTLESLOTLEFT] = irrDriver->getTexture("textures/battle/slot_left.png");
	Images[IMAGE_BATTLESLOTRIGHT] = irrDriver->getTexture("textures/battle/slot_right.png");
	Images[IMAGE_BATTLEEXPERIENCE] = irrDriver->getTexture("textures/battle/experience.png");
	Images[IMAGE_BATTLECOINS] = irrDriver->getTexture("textures/battle/coins.png");
	Images[IMAGE_BATTLECHEST] = irrDriver->getTexture("textures/battle/chest.png");
	Images[IMAGE_BATTLETARGET] = irrDriver->getTexture("textures/battle/target.png");
	Images[IMAGE_INVENTORY] = irrDriver->getTexture("textures/interface/inventory.png");
	Images[IMAGE_VENDOR] = irrDriver->getTexture("textures/interface/vendor.png");
	Images[IMAGE_TRADE] = irrDriver->getTexture("textures/interface/trade.png");
	Images[IMAGE_TRADER] = irrDriver->getTexture("textures/interface/trader.png");
	Images[IMAGE_PLUS] = irrDriver->getTexture("textures/interface/plus.png");
	Images[IMAGE_MINUS] = irrDriver->getTexture("textures/interface/minus.png");

	irrDriver->getTexture("textures/interface/hud_spawn.png");
	irrDriver->getTexture("textures/interface/hud_inventory.png");
	irrDriver->getTexture("textures/interface/hud_trade.png");
	irrDriver->getTexture("textures/interface/hud_character.png");
	irrDriver->getTexture("textures/interface/hud_skills.png");
	irrDriver->getTexture("textures/interface/hud_menu.png");

	return 1;
}

// Closes the graphics system
int GraphicsClass::Close() 
{
	// Close irrlicht
	irrDevice->drop();

	return 1;
}

// Erases the buffer and sets irrlicht up for the next frame
void GraphicsClass::BeginFrame() 
{
	irrDriver->beginScene(true, true, ClearColor);
}

// Draws the buffer to the screen
void GraphicsClass::EndFrame() 
{
	irrDriver->endScene();
}

// Draws an 2d image centered about a point
void GraphicsClass::DrawCenteredImage(const ITexture *TTexture, int TPositionX, int TPositionY, const SColor &TColor) 
{
	irrDriver->draw2DImage(TTexture, position2di(TPositionX - (TTexture->getSize().Width >> 1), TPositionY - (TTexture->getSize().Height >> 1)), rect<s32>(0, 0, TTexture->getSize().Width, TTexture->getSize().Height), 0, TColor, true);
}

// Sets the current font
void GraphicsClass::SetFont(int TType) 
{
	CurrentFont = TType;
	Skin->setFont(Fonts[CurrentFont]);
}

// Adds text to the screen
IGUIStaticText *GraphicsClass::AddText(const char *TText, int TPositionX, int TPositionY, AlignType TAlignType, IGUIElement *TParent) 
{
	// Convert string
	stringw Text(TText);

	// Get dimensions
	dimension2du TextArea = Fonts[CurrentFont]->getDimension(Text.c_str());

	switch(TAlignType) {
		case ALIGN_LEFT:
		break;
		case ALIGN_CENTER:
			TPositionX -= TextArea.Width >> 1;
		break;
		case ALIGN_RIGHT:
			TPositionX -= TextArea.Width;
		break;
	}

	// Draw text
	return irrGUI->addStaticText(Text.c_str(), rect<s32>(TPositionX, TPositionY, TPositionX + TextArea.Width, TPositionY + TextArea.Height), 0, false, TParent);
}

// Draws text to the screen
void GraphicsClass::RenderText(const char *TText, int TPositionX, int TPositionY, AlignType TAlignType, const SColor &TColor) 
{
	// Convert string
	stringw Text(TText);

	// Get dimensions
	dimension2du TextArea = Fonts[CurrentFont]->getDimension(Text.c_str());

	switch(TAlignType) 
	{
		case ALIGN_LEFT:
		break;
		case ALIGN_CENTER:
			TPositionX -= TextArea.Width >> 1;
		break;
		case ALIGN_RIGHT:
			TPositionX -= TextArea.Width;
		break;
	}

	// Draw text
	Fonts[CurrentFont]->draw(Text.c_str(), rect<s32>(TPositionX, TPositionY, TPositionX + TextArea.Width, TPositionY + TextArea.Height), TColor);
}

// Return a centered rect
rect<s32> GraphicsClass::GetCenteredRect(int TPositionX, int TPositionY, int TWidth, int THeight) 
{
	TWidth >>= 1;
	THeight >>= 1;

	return rect<s32>(TPositionX - TWidth, TPositionY - THeight, TPositionX + TWidth, TPositionY + THeight);
}

// Return a rect
rect<s32> GraphicsClass::GetRect(int TPositionX, int TPositionY, int TWidth, int THeight) 
{
	return rect<s32>(TPositionX, TPositionY, TPositionX + TWidth, TPositionY + THeight);
}

// Clear all the GUI elements
void GraphicsClass::Clear() 
{
	irrGUI->clear();
}

// Draws an interface image
void GraphicsClass::DrawImage(ImageType TType, int TPositionX, int TPositionY, const SColor &TColor) 
{
	GraphicsClass::Instance().DrawCenteredImage(Images[TType], TPositionX, TPositionY, TColor);
}

// Draws a health or mana bar
void GraphicsClass::DrawBar(ImageType TType, int TPositionX, int TPositionY, float TPercent, int TWidth, int THeight) 
{
	irrDriver->draw2DImage(Images[TType + 1], position2di(TPositionX, TPositionY), rect<s32>(0, 0, TWidth, THeight), 0, SColor(255, 255, 255, 255), true);
	irrDriver->draw2DImage(Images[TType], position2di(TPositionX, TPositionY), rect<s32>(0, 0, (int)(TWidth * TPercent), THeight), 0, SColor(255, 255, 255, 255), true);
}

// Draws a tiled background
void GraphicsClass::DrawBackground(ImageType TType, int TPositionX, int TPositionY, int TWidth, int THeight, const SColor &TColor) 
{
	irrDriver->draw2DImage(Images[TType], position2di(TPositionX, TPositionY), rect<s32>(0, 0, TWidth, THeight), 0, TColor, true);
}

void GraphicsClass::DrawHex(float _x, float _y, float _w, float _h, bool _solid, const SColor &TColor)
{
	static f32 hex_vrt[6][2] = {{0.0f,0.5f},{0.25f,1.0f},{0.75f,1.0f},{1.0f,0.5f},{0.75f,0.0f},{0.25f,0.0f}};
	video::S3DVertex vertices[6];

    vertices[0].Pos = core::vector3df(_x - _w/2 + hex_vrt[0][0]*_w,_y - _h/2 + hex_vrt[0][1]*_h,0);
	vertices[1].Pos = core::vector3df(_x - _w/2 + hex_vrt[1][0]*_w,_y - _h/2 + hex_vrt[1][1]*_h,0);
	vertices[2].Pos = core::vector3df(_x - _w/2 + hex_vrt[2][0]*_w,_y - _h/2 + hex_vrt[2][1]*_h,0);
	vertices[3].Pos = core::vector3df(_x - _w/2 + hex_vrt[3][0]*_w,_y - _h/2 + hex_vrt[3][1]*_h,0);
	vertices[4].Pos = core::vector3df(_x - _w/2 + hex_vrt[4][0]*_w,_y - _h/2 + hex_vrt[4][1]*_h,0);
	vertices[5].Pos = core::vector3df(_x - _w/2 + hex_vrt[5][0]*_w,_y - _h/2 + hex_vrt[5][1]*_h,0);

	for(int i=0;i<6;i++)
	{
		vertices[i].Color = TColor;
	}
    
	static u16 index[] = {5,1,0,2,1,5,5,4,2,4,3,2};
    
    /*video::SMaterial m;
    m.DiffuseColor = TColor;
	m.MaterialType = EMT_SOLID;
	m.Lighting = false;

    irrDriver->setMaterial(m);*/
	irrDriver->draw2DVertexPrimitiveList(vertices, 6, index, 4, EVT_STANDARD, EPT_TRIANGLES);
}

void GraphicsClass::DrawPlayer(float _x, float _y, float _w, float _h, char _dir, const SColor &TColor)
{
	static f32 vrt[4][2] = {{0.0f,0.0f},{0.5f,1.0f},{1.0f,0.0f},{0.5f,0.3f}};
	video::S3DVertex vertices[4];

	if(_dir<0)
		_dir = 0;
	if(_dir>5)
		_dir = 5;

	vertices[0].Pos = core::vector3df(_x - _w/2 + vrt[0][0]*_w,_y - _h/2 + vrt[0][1]*_h,0);
	vertices[1].Pos = core::vector3df(_x - _w/2 + vrt[1][0]*_w,_y - _h/2 + vrt[1][1]*_h,0);
	vertices[2].Pos = core::vector3df(_x - _w/2 + vrt[2][0]*_w,_y - _h/2 + vrt[2][1]*_h,0);
	vertices[3].Pos = core::vector3df(_x - _w/2 + vrt[3][0]*_w,_y - _h/2 + vrt[3][1]*_h,0);

	for(int i=0;i<4;i++)
	{
		vertices[i].Color = TColor;
		vertices[i].Pos.rotateXYBy(180.0f + _dir*60.0f,vector3d<f32>(_x,_y,0.0f));
	}

	static u16 index[] = {3,1,0,2,1,3};

	irrDriver->draw2DVertexPrimitiveList(vertices, 4, index, 2, EVT_STANDARD, EPT_TRIANGLES);
}
